﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace A1
{
    abstract class Paddle
    {
        protected Game1.Position position; // The position of the paddle
        protected Game1.Difficulty difficulty; //The difficulty of the AI
        protected Rectangle rec; // The bounding rectangle
        protected Texture2D sprite; // The texture
        protected Ball ball; // The ball
        protected TimeSpan hammerTime; // The length of time to allow a powerup to last
        protected TimeSpan previousTime; // The last time a powerup was activated
        private TimeSpan chargeSpan; // The span of time to allow a charge
        protected PowerUp.Powers power; // The power the paddle has
        protected bool powerActive; // Whether the paddle's power is active
        protected bool disabled;
        private bool chargeActive; //Whether charge is active
        private TimeSpan chargeTime; // The last tiem charge was activated
        protected int chargeDistance; // The distance to move charge
        protected GameTime gameTime; // The gametime object
        private TimeSpan coolTime; // The time to disable charging
        protected int score; // The paddle's score
        protected bool newPower; // whether we have a new power

        /// <summary>
        /// Gets or sets whether a Paddle currently has a power active
        /// </summary>
        public bool PowerActive
        {
            get { return powerActive; }
            set { powerActive = value; }
        }
        /// <summary>
        /// Whether a new power has been acquired or we are still running a power
        /// </summary>
        public bool NewPower
        {
            get { return newPower; }
            set { newPower = value; }
        }
        /// <summary>
        /// The paddle's current power 
        /// </summary>
        public PowerUp.Powers Power
        {
            get { return power; }
            set { power = value; }
        }
        /// <summary>
        /// The last time a powerup was acquired by the paddle
        /// </summary>
        public TimeSpan PreviousTime
        {
            get { return previousTime; }
            set { previousTime = value; }
        }
        /// <summary>
        /// The position of the paddle
        /// </summary>
        public Game1.Position Position
        {
            get { return position; }
        }
        /// <summary>
        /// The bounding rectangle of the paddle
        /// </summary>
        public Rectangle Rec
        {
            get { return rec; }
            set { rec = value; }
        }
        /// <summary>
        /// The sprite
        /// </summary>
        public Texture2D Sprite
        {
            get { return sprite; }
            set { sprite = value; }
        }
        /// <summary>
        /// The player's score
        /// </summary>
        public int Score
        {
            get { return score; }
            set { score = value; }
        }
        /// <summary>
        /// Create a new paddle
        /// </summary>
        /// <param name="s">The texture of the paddle</param>
        /// <param name="b">The ball</param>
        /// <param name="position">The position of the paddle</param>
        /// <param name="height">The game height</param>
        /// <param name="width">The game wisth</param>
        /// <param name="gameTime">the game time object</param>
        public Paddle(Texture2D s, Ball b, Game1.Position position, int height, int width, GameTime gameTime)
        {
            score = 10;
            switch (position)
            {
                case Game1.Position.Left:
                    rec = new Rectangle(30, (height / 2) - 35, 10, 70);
                    break;
                case Game1.Position.Top:
                    rec = new Rectangle((width / 2) - 35, 30, 70, 10);
                    break;
                case Game1.Position.Bottom:
                    rec = new Rectangle(width / 2 - 35, height - 30, 70, 10);
                    break;
                case Game1.Position.Right:
                    rec = new Rectangle(width - 30, (height / 2) - 35, 10, 70);
                    break;
                default:
                    rec = new Rectangle(30, (height / 2) - 35, 10, 70);
                    break;
            }

            this.position = position;
            this.gameTime = gameTime;
            sprite = s;
            ball = b;
            hammerTime = TimeSpan.FromSeconds(6);
            chargeSpan = TimeSpan.FromMilliseconds(250);
            coolTime = TimeSpan.FromSeconds(2);
            chargeDistance = 10;

        }
        /// <summary>
        /// Allows a user to "charge the ball"
        /// </summary>
        protected void Charge()
        {
            if (chargeActive)
            {
                if (gameTime.TotalGameTime - chargeTime > chargeSpan)
                {
                    switch (position)
                    {
                        case Game1.Position.Right:
                            rec.X += chargeDistance;
                            //rec.Width
                            break;
                        case Game1.Position.Left:
                            rec.X -= chargeDistance;
                            break;
                        case Game1.Position.Top:
                            rec.Y -= chargeDistance;
                            break;
                        case Game1.Position.Bottom:
                            rec.Y += chargeDistance;
                            break;
                    }
                    chargeActive = false;
                    chargeTime = gameTime.TotalGameTime;
                }
            }
            else
            {
                if (gameTime.TotalGameTime - chargeTime > coolTime)
                {
                    chargeTime = gameTime.TotalGameTime;
                    switch (position)
                    {
                        case Game1.Position.Right:
                            rec.X -= chargeDistance;
                            break;
                        case Game1.Position.Left:
                            rec.X += chargeDistance;
                            break;
                        case Game1.Position.Top:
                            rec.Y += chargeDistance;
                            break;
                        case Game1.Position.Bottom:
                            rec.Y -= chargeDistance;
                            break;
                    }
                    chargeActive = true;
                }
            }
        }

        /// <summary>
        /// Allows a power to timeout/run
        /// </summary>
        /// <param name="gameTime">the gametime object</param>
        protected void PowerCountdown(GameTime gameTime)
        {
            if (powerActive)
            {
                if (gameTime.TotalGameTime - previousTime > hammerTime)
                {
                    switch (power)
                    {
                        case PowerUp.Powers.Enlarge:
                            switch (position)
                            {
                                case Game1.Position.Left:
                                case Game1.Position.Right:
                                    rec.Height *= 2;
                                    break;

                                case Game1.Position.Bottom:
                                case Game1.Position.Top:
                                    rec.Width *= 2;
                                    break;

                            }
                            break;
                            

                        case PowerUp.Powers.Shrink:
                            switch (position)
                            {
                                case Game1.Position.Left:
                                case Game1.Position.Right:
                                    rec.Height = rec.Height / 2;
                                    break;
                                case Game1.Position.Bottom:
                                case Game1.Position.Top:
                                    rec.Width /= 2;
                                    break;
                            }
                            break;
                            

                        case PowerUp.Powers.Magnet:
                            { break; }
                    }
                    power = PowerUp.Powers.Null;
                    powerActive = false;
                }
            }
        }
        /// <summary>
        /// Activate a power
        /// </summary>
        protected void ApplyPower()
        {
            if (newPower)
            {
                switch (power)
                {
                    case PowerUp.Powers.Enlarge:
                        switch (position)
                        {
                            case Game1.Position.Left:
                            case Game1.Position.Right:
                                rec.Height = rec.Height / 2;
                                break;
                            case Game1.Position.Bottom:
                            case Game1.Position.Top:
                                rec.Width /= 2;
                                break;
                        }
                        break;

                    case PowerUp.Powers.Shrink:
                        switch (position)
                        {
                            case Game1.Position.Left:
                            case Game1.Position.Right:
                                rec.Height *= 2;
                                break;
                            case Game1.Position.Bottom:
                            case Game1.Position.Top:
                                rec.Width *= 2;
                                break;
                        }
                        break;
                        

                    case PowerUp.Powers.Magnet:
                        { break; }
                }
                powerActive = true;
                newPower = false;
            }
        }
        /// <summary>
        /// Update the paddle - meant to be overridden
        /// </summary>
        /// <param name="gameTime">the game time object</param>
        public abstract void Update(GameTime gameTime);

        /// <summary>
        /// Draw the paddle
        /// </summary>
        /// <param name="spriteBatch">The spritebatch object</param>
        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(sprite, rec, Color.White);
        }
    }
}
